package com.gzhryc.weixin.gzh;


import com.gzhryc.common.json.JsonTools;
import com.gzhryc.weixin.api.DefaultApiResponse;
import com.gzhryc.weixin.api.authority.models.Template;
import com.gzhryc.weixin.gzh.models.AccessToken;
import com.gzhryc.weixin.gzh.msg.AccessTokenResponse;
import com.gzhryc.weixin.gzh.msg.Oauth2AccessToken;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Date;

/**
 * 微信入口凭据服务
 *
 * @author 张浩
 * @version 0.1.0
 */
public class WxAuthorityApi extends AbsWeixinApi {

    private static Logger log = Logger.getLogger(WxAuthorityApi.class);

    private String grant_type = "client_credential";

    public WxAuthorityApi(AccessToken accessToken) {
        super(accessToken);
    }

    /**
     * 获取普通AccessToken
     *
     * @param
     * @return
     */
    public AccessTokenResponse getAccessTokenResponse() {
        CloseableHttpResponse response = null;
        try {
            log.info("调用获取AccessToken接口appid= " + accessToken.getAppid() + "，secret= " + accessToken.getSecret());
            CloseableHttpClient httpclient = HttpClients.createDefault();
            // 设置请求配置
            RequestConfig requestConfig = RequestConfig.custom()
                    .setConnectTimeout(5000) // 连接超时时间5秒
                    .setSocketTimeout(10000)  // 读取超时时间10秒
                    .build();

            URI uri = new URIBuilder()
                    .setScheme("https")
                    .setHost("api.weixin.qq.com")
                    .setPath("/cgi-bin/token")
                    .setParameter("grant_type", grant_type)
                    .setParameter("appid", accessToken.getAppid())
                    .setParameter("secret", accessToken.getSecret())
                    .build();
            HttpGet httpget = new HttpGet(uri);
            httpget.setConfig(requestConfig);
            response = httpclient.execute(httpget);
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                String str = EntityUtils.toString(entity);
                if (StringUtils.isNotBlank(str)) {
                    if (isError(str)) {
                        DefaultApiResponse defaultApiResponse = JsonTools.fromJson(str, DefaultApiResponse.class);
                        defaultApiResponse.setCreateDate(new Date());
                        accessToken.queuePut(defaultApiResponse);
                    } else {
                        return JsonTools.fromJson(str, AccessTokenResponse.class);
                    }
                }
            }
        } catch (Exception e) {
            log.error("getAccessToken error", e);
        } finally {
            if (response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    /**
     * 获取Oauth2的AccessToken
     *
     * @param code 用户授权Code
     * @return
     */
    public Oauth2AccessToken getOauth2AccessToken(String code) {
        CloseableHttpResponse response = null;
        try {
            CloseableHttpClient httpclient = HttpClients.createDefault();
            URI uri = new URIBuilder()
                    .setScheme("https")
                    .setHost("api.weixin.qq.com")
                    .setPath("/sns/oauth2/access_token")
                    .setParameter("appid", accessToken.getAppid())
                    .setParameter("secret", accessToken.getSecret())
                    .setParameter("code", code)
                    .setParameter("grant_type", "authorization_code")
                    .build();
            HttpGet httpget = new HttpGet(uri);
            response = httpclient.execute(httpget);
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                String str = EntityUtils.toString(entity, Charset.forName("UTF-8"));
                if (isError(str)) {
                    DefaultApiResponse defaultApiResponse = JsonTools.fromJson(str, DefaultApiResponse.class);
                    defaultApiResponse.setCreateDate(new Date());
                    accessToken.queuePut(defaultApiResponse);
                } else {
                    return JsonTools.fromJson(str, Oauth2AccessToken.class);
                }
            }
        } catch (Exception e) {
            log.error("getOauth2AccessToken error", e);
        } finally {
            if (response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    public boolean sendTemplateMsg(Template template) {
        CloseableHttpResponse response = null;
        boolean flag = false;
        if (template != null) {
            URI uri = null;
            try {
                CloseableHttpClient httpclient = HttpClients.createDefault();
                uri = new URIBuilder()
                        .setScheme("https")
                        .setHost("api.weixin.qq.com")
                        .setPath("/cgi-bin/message/subscribe/send")
                        .setParameter("access_token", accessToken.getAccess_token())
                        .build();
                StringEntity strEntity = new StringEntity(template.toJSON(),
                        ContentType.create("application/json", Consts.UTF_8));
                HttpPost httppost = new HttpPost(uri);
                httppost.setEntity(strEntity);
                response = httpclient.execute(httppost);
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    String str = EntityUtils.toString(entity, StandardCharsets.UTF_8);
                    if (StringUtils.isNotBlank(str)) {
                        DefaultApiResponse apiResponse = JsonTools.fromJson(str, DefaultApiResponse.class);
                        if (apiResponse != null) {
                            if (isError(str)) {
                                DefaultApiResponse defaultApiResponse = JsonTools.fromJson(str, DefaultApiResponse.class);
                                defaultApiResponse.setCreateDate(new Date());
                                accessToken.queuePut(defaultApiResponse);
                            }else {
                                flag = true;
                            }
                            log.info("模板消息发送结果:" + apiResponse.getErrcode() + ","
                                    + apiResponse.getErrmsg() +
                                    ",access_token:" + accessToken.getAccess_token() + ",最后设置时间:" + accessToken.getLastSetDate());
                        }
                    }
                }
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
        }
        return flag;
    }

    public String getOAuthUrl(String redirectUri, String state) {
        return getOAuthUrl(accessToken.getAppid(), redirectUri, state);
    }

    public String getOAuthUrl2(String redirectUri, String state) {
        return getOAuthUrl2(accessToken.getAppid(), redirectUri, state);
    }

    /**
     * 生成静默的授权页面路径
     *
     * @param appId
     * @param redirectUri
     * @return
     */
    public static String getOAuthUrl(String appId, String redirectUri, String state) {
        try {
            if (state == null) {
                state = "";
            }
            URIBuilder uriBuilder = new URIBuilder()
                    .setScheme("https")
                    .setHost("open.weixin.qq.com")
                    .setPath("/connect/oauth2/authorize")
                    .setParameter("appid", appId)
                    .setParameter("redirect_uri", redirectUri)
                    .setParameter("response_type", "code")
                    .setParameter("scope", "snsapi_base")
                    .setParameter("state", state);
            return uriBuilder.build().toString() + "#wechat_redirect";
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 生成授权页面路径
     *
     * @param appId
     * @param redirectUri
     * @param state
     * @return
     */
    public static String getOAuthUrl2(String appId, String redirectUri, String state) {
        try {
            if (state == null) {
                state = "";
            }
            URIBuilder uriBuilder = new URIBuilder()
                    .setScheme("https")
                    .setHost("open.weixin.qq.com")
                    .setPath("/connect/oauth2/authorize")
                    .setParameter("appid", appId)
                    .setParameter("redirect_uri", redirectUri)
                    .setParameter("response_type", "code")
                    .setParameter("scope", "snsapi_userinfo")
                    .setParameter("state", state);
            return uriBuilder.build().toString() + "#wechat_redirect";
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }

        return null;
    }
}
